/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  ** This notice applies to any and all portions of this file
  * that are not between comment pairs USER CODE BEGIN and
  * USER CODE END. Other portions of this file, whether 
  * inserted by the user or by software development tools
  * are owned by their respective copyright owners.
  *
  * COPYRIGHT(c) 2019 STMicroelectronics
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "dma.h"
#include "rtc.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include <string.h>

#include "sht3x.h"
#include "oled.h"
#include "flash.h"
#include "nbiot.h"
#include "TLVUtil.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

#define FLASH_QC_FLAG_VAL  		0xFFFFFF01
#define FLASH_INIT_FLAG_VAL  	0xFFFFFF02
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
Message stMsg;
char s_QCk1flag = 0, s_QCk2flag = 0, s_TimeToUpdata = 0,s_SwitchOLED = 0, s_ClearOLED = 1, s_UserShow = 1;
char 	acAtResp[256] = {0}, acOledLineMsg[17] = {0};

uint16_t usValCnt = 0;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void STOP_MCU(void);
void SYSCLKConfig_RESET(void);
void SYSCLKConfig_RESET_UART(void);
void KE1_Test_Itself(void);
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
	char acAppVer[12] = {0};
	uint32_t uiFlashInitFlag = 0;
	float	temperature = 0.0; // temperature
	float	humidity = 0.0; // relative humidity [%RH]
	unsigned short usVoltage = 0, usLight = 0, usSound = 0;
	NB_STA atRet = NB_OK;
	#if defined TCP_MODE || defined UDP_MODE
	int iSz = 0;
	unsigned char ucReadDone = 0 ,ucReadTry = 0;
	#endif
	unsigned char ucTryCnt = 0, ucInitFlag = 0, ucModuleCheckCnt = 0;
	M_STEP ucStep = M_INIT;
	//SCB->VTOR = FLASH_BASE | 0x4000;
	//__set_PRIMASK(0);
	
	memset(&stMsg, 0, sizeof(Message));

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();
  MX_USART3_UART_Init();
  MX_ADC1_Init();
  MX_TIM2_Init();
  MX_RTC_Init();
  MX_TIM7_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
	
	printf("Welcome to NB-IoT-Lab!\r\n");
	sprintf(acAppVer, "%s%s", APP_TYPE, APP_VERSION);
	UART_Enable_Receive_IT();
	ADC_Start();
	SHT3X_SetI2cAdr(0x44);
	OLED_Init();
	Flash_Read_Flag(&uiFlashInitFlag);
	//printf("flag:%08X\n", uiFlashInitFlag);
	if(0xFFFFFFFF == uiFlashInitFlag){
		KE1_Test_Itself();
	}
	
	OLED_DrawLogo();
	OLED_ShowString(60, 0, (uint8_t *)acAppVer, 8);
	TIM_PWM_Start();HAL_Delay(300);TIM_PWM_Stop();
	
	HAL_Delay(1000);
	
	OLED_ShowKE1();HAL_Delay(1000);
	
	//
	#ifdef TCP_MODE
	stMsg.acNetType = 1;
	stMsg.usPort = 7386; // TCP
	sprintf(stMsg.acIP, "114.215.100.225");
	#elif defined UDP_MODE
	stMsg.usPort = 7385; // UDP
	sprintf(stMsg.acIP, "114.215.100.225");
	#elif defined HW_IOT_MODE
	stMsg.usPort = 5683;
	sprintf(stMsg.acIP, "180.101.147.115");
	#else
	TIM_PWM_Start();
	while(){
	;
	}
	#endif
	
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		#if 1
		
		if(0 == usValCnt){
			usVoltage = ADC_Battery_Voltage();
		}
		usValCnt++;
		if(15 ==  usValCnt){
			usValCnt = 0;
		}
		usLight = ADC_Light_Val();
		usSound = ADC_Sound_Val();
		
		SHT3X_GetTempAndHumi(&temperature, &humidity, REPEATAB_HIGH, MODE_CLKSTRETCH, 2);
		//ADC_Stop();
		
		stMsg.usVoltage = usVoltage;
		stMsg.usSound = usSound;
		stMsg.usLight = usLight;
		stMsg.usHumi = (uint16_t)(humidity*100);
		stMsg.iTemp = (int)(temperature*100);
		
		if(1 == s_ClearOLED){
			OLED_Clear();
			s_ClearOLED = 0;
		}
		if(0 == s_UserShow){
			if(0 == s_SwitchOLED){
				OLED_ShowT_H(temperature, humidity, (char *)stMsg.aucSignal);
			}else if(1 == s_SwitchOLED){
				OLED_ShowS_L(usSound, usLight);
			}else if(2 == s_SwitchOLED){
				OLED_ShowVoltage(usVoltage);
			}
		}
		if(M_INIT == ucStep){
			OLED_Clear();
			stMsg.iFd = 0;
			HAL_GPIO_WritePin(RGB_R_GPIO_Port, RGB_R_Pin, GPIO_PIN_RESET);
			#ifdef HW_IOT_MODE
			atRet = nbiot_OceanConnect_init();
			#else
			atRet = nbiot_module_init();
			#endif
			if(NB_OK == atRet){
				atRet = nbiot_get_module_info(&stMsg);
			}
			
			if(NB_OK == atRet){
				HAL_GPIO_WritePin(RGB_R_GPIO_Port, RGB_R_Pin, GPIO_PIN_SET);			
				ucStep = M_CHECK_NET;
			}else{
				//SYSCLKConfig_RESET_UART();
				printf("NVIC_SystemReset\n");
				NVIC_SystemReset();
				ucStep = M_INIT;
			}
		}else if(M_CHECK_NET == ucStep){
			TIM_Stop();
			HAL_GPIO_WritePin(RGB_G_GPIO_Port, RGB_B_Pin, GPIO_PIN_RESET);
			do{
				TIM_PWM_Start();
				nbiot_get_signl_val((char *)stMsg.aucSignal);
				TIM_PWM_Stop();				
				atRet = nbiot_get_reg_sta((char *)&stMsg.acRegSta, (char *)stMsg.aucLBS);
				if(NB_TIMEOUT == atRet){
					SYSCLKConfig_RESET_UART();
				}else if(NB_ERROR == atRet){
					 break;
				}
				ucTryCnt++;
				if(0 == stMsg.acRegSta){
					if(20 == ucTryCnt) {
						break;
					}
				}else{
					if(20 == ucTryCnt) {
						break;
					}
				}
				if(0 == stMsg.acRegSta){
					HAL_Delay(3000);
				}else{
					HAL_Delay(3000);
				}
			}while(stMsg.acRegSta != 0x31 && stMsg.acRegSta != 0x35 /* && '9' != stMsg.aucSignal[0]*/);
			ucTryCnt = 0;
			HAL_GPIO_WritePin(RGB_G_GPIO_Port, RGB_B_Pin, GPIO_PIN_SET);
			if(stMsg.acRegSta == 0x31 || stMsg.acRegSta == 0x35){
				#ifdef HW_IOT_MODE
				TIM_Start();
				s_UserShow = 0;
				s_ClearOLED = 1;
				stMsg.iFd = 1;
				ucStep = M_UP_SENSER;
				#else
				ucStep = M_GET_SOCKET;
				#endif
			}else{
				ucStep = M_INIT;
			}
		}else if(M_GET_SOCKET == ucStep){
			if(0 < stMsg.iFd){
				nbiot_close_socket(stMsg.iFd); stMsg.iFd = 0;
			}
			//HAL_Delay(1000);
			//uart3_refresh_buf();
			if(0 == stMsg.acIP[0]){
				atRet = nbiot_dns("blog.hanxe.com", stMsg.acIP, 10);
				if(NB_OK != atRet){
					continue;
				}
			}
			#ifdef TCP_MODE
			stMsg.iFd = nbiot_create_tcp(3000);
			if(0 < stMsg.iFd){
				atRet = nbiot_tcp_connect(stMsg.iFd, stMsg.acIP, stMsg.usPort);
				printf("Connect ret:%d\n", atRet);
				if(NB_OK != atRet){
					nbiot_close_socket(stMsg.iFd); stMsg.iFd = 0;
				}
			}
			#else
			stMsg.iFd = nbiot_create_upd(3000);
			#endif
			
			if(0 < stMsg.iFd){
				if(FLASH_INIT_FLAG_VAL == uiFlashInitFlag && 1 == ucInitFlag){
					ucStep = M_UP_SENSER;
				}else{
					ucStep = M_UP_DEV; 
				}
				TIM_Start();
				s_UserShow = 0;
				s_ClearOLED = 1;
			}else{
				ucTryCnt++;
				if(3 == ucTryCnt) {
					ucStep = M_INIT; ucTryCnt = 0;
				}
			}
		}else if(M_UP_DEV == ucStep){
			pack_module_info_message(&stMsg);
			if(0 < stMsg.usMsgLen){
				#ifdef TCP_MODE
				atRet = nbiot_tcp_send(stMsg.iFd, stMsg.aucMsgData, stMsg.usMsgLen, 30);
				#elif defined UDP_MODE
				atRet = nbiot_udp_send(stMsg.acIP, stMsg.usPort, stMsg.iFd, stMsg.aucMsgData, stMsg.usMsgLen, 30);
				#elif defined HW_IOT_MODE
				
				#endif
				if(NB_ERROR == atRet){
					printf("Send data failed\n");
					ucStep = M_CHECK_NET;
				}else{
					ucStep = M_DELAY;
				}
				memset(stMsg.aucMsgData, 0, sizeof(stMsg.aucMsgData)); stMsg.usMsgLen = 0;
			}
		}else if(M_UP_SENSER == ucStep){
			nbiot_get_signl_val((char *)stMsg.aucSignal);
			OLED_Show_UP_Flag(1);
			stMsg.ucLED = 0;
			stMsg.ucSwitch1 = 0;
			stMsg.ucSwitch2 = 0;
			if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(RGB_B_GPIO_Port, RGB_B_Pin)){
				stMsg.ucLED = 1;
			}
			if(HAL_GPIO_ReadPin(JDQ1_GPIO_Port, JDQ1_Pin)){
				stMsg.ucSwitch1 = 1;
			}
			if(HAL_GPIO_ReadPin(JDQ2_GPIO_Port, JDQ2_Pin)){
				stMsg.ucSwitch2 = 1;
			}
			#ifdef HW_IOT_MODE
			stMsg.iCellID = 0;
			stMsg.ucECL = 0;
			stMsg.iRSRP = 0;
			stMsg.iSNR = 0;
			nbiot_get_nuestats(&stMsg.iRSRP, &stMsg.iSNR, &stMsg.iCellID, &stMsg.ucECL);
			printf("[r:%d,c:%d,e:%d,s:%d,S:%s]\r\n", stMsg.iRSRP, stMsg.iCellID, stMsg.ucECL, stMsg.iSNR,stMsg.aucSignal);
			pack_huawei_senser_info_msg(&stMsg);
			#else
			pack_senser_info_message(&stMsg);
			#endif
			
			if(0 < stMsg.usMsgLen){
				#ifdef TCP_MODE
				atRet = nbiot_tcp_send(stMsg.iFd, stMsg.aucMsgData, stMsg.usMsgLen, 30);
				#elif defined UDP_MODE
				atRet = nbiot_udp_send(stMsg.acIP, stMsg.usPort, stMsg.iFd, stMsg.aucMsgData, stMsg.usMsgLen, 30);
				#elif defined HW_IOT_MODE
				atRet = nbiot_coap_send((char *)stMsg.aucMsgData, stMsg.usMsgLen, 30);
				#endif
				if(NB_ERROR == atRet){
					printf("Send data failed\n");
					ucStep = M_CHECK_NET;
					#ifdef HW_IOT_MODE
					OLED_Clear();
					OLED_ShowNoRegister((char *)stMsg.aucIMEI);
					s_ClearOLED = 1;
					HAL_Delay(10000);
					#endif
				}else{
					ucStep = M_DELAY;
				}
				memset(stMsg.aucMsgData, 0, sizeof(stMsg.aucMsgData)); stMsg.usMsgLen = 0;
			}
		}else if(M_CTL_ACK == ucStep){
			#ifdef HW_IOT_MODE
			stMsg.ucACK = 0;
			stMsg.ucLED = 0;
			stMsg.ucSwitch1 = 0;
			stMsg.ucSwitch2 = 0;
			if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(RGB_B_GPIO_Port, RGB_B_Pin)){
				stMsg.ucLED = 1;
			}
			if(HAL_GPIO_ReadPin(JDQ1_GPIO_Port, JDQ1_Pin)){
				stMsg.ucSwitch1 = 1;
			}
			if(HAL_GPIO_ReadPin(JDQ2_GPIO_Port, JDQ2_Pin)){
				stMsg.ucSwitch2 = 1;
			}
			pack_huawei_ctl_ack_msg(&stMsg);
			#endif
			if(0 < stMsg.usMsgLen){
				#ifdef HW_IOT_MODE
				atRet = nbiot_coap_send((char *)stMsg.aucMsgData, stMsg.usMsgLen, 30);
				#endif
				if(NB_ERROR == atRet){
					printf("Send data failed\n");
					ucStep = M_CHECK_NET;
				}else{
					ucStep = M_DELAY;
				}
				memset(stMsg.aucMsgData, 0, sizeof(stMsg.aucMsgData)); stMsg.usMsgLen = 0;
			}
		}else if(M_DELAY == ucStep){
			HAL_Delay(1500);
			//nbiot_send_at_cmd(AT_CSQ, 500);
		}else if(M_MCU_STOP == ucStep){
			
			OLED_Clear();
			nbiot_module_switch(0);
			
			STOP_MCU();
			
			//HAL_Delay(50000);
			SYSCLKConfig_RESET();	
			
			nbiot_module_switch(1);
			
			ucStep = M_CHECK_NET;
			continue;
		}
		if(0 < stMsg.iFd){
			#ifdef HW_IOT_MODE
			atRet = nbiot_coap_wait(&stMsg, 2);
			#else
			atRet = nbiot_wait_data(&stMsg, 2);
			#endif
			//printf("Step:%d, ret:%d\n", ucStep, atRet);
			if(NB_DATA_IN == atRet){
				#ifdef HW_IOT_MODE
				printf("<<:[%d]%s\n", stMsg.usRevLen, stMsg.aucMsgData);
				OLED_Show_UP_Flag(0);
				#else
				iSz = sizeof(stMsg.aucMsgData);
				atRet = nbiot_data_recv(stMsg.iFd, (int *)&stMsg.usRevLen, stMsg.aucMsgData, iSz, 10);
				if(NB_OK == atRet){
					ucReadDone = 1; ucReadTry = 0;
					if(FLASH_INIT_FLAG_VAL != uiFlashInitFlag || 0 == ucInitFlag){
						Flash_Write_Flag(FLASH_INIT_FLAG_VAL);
						uiFlashInitFlag = FLASH_INIT_FLAG_VAL;
						ucInitFlag = 1;
						ucStep = M_UP_SENSER;
					}
					OLED_Show_UP_Flag(0);
				}
				#endif
			}else if(NB_OK == atRet){
				//printf("Signal:%s\n", stMsg.aucSignal);
				ucModuleCheckCnt = 0;
			}else if(NB_TIMEOUT == atRet){
				//ucModuleCheckCnt++;
			}else if(NB_REG_CHANGED == atRet){
				//OLED_Show_UP_Flag(2);
				//ucStep = M_CHECK_NET;
			}else if(NB_NET_CLOSED == atRet){
				OLED_Show_UP_Flag(2);
				ucStep = M_CHECK_NET;
			}
		}
		
		if(10 == ucModuleCheckCnt){
			printf("Module Check timeout-SystemReset\n");
			NVIC_SystemReset();
		}
		
		if(1 == s_TimeToUpdata){
			s_TimeToUpdata = 0;
			
			if(FLASH_INIT_FLAG_VAL != uiFlashInitFlag){
				#ifdef HW_IOT_MODE
				ucStep = M_UP_SENSER;
				#else
				ucStep = M_UP_DEV;
				#endif
			}else{
				ucStep = M_UP_SENSER;
			}
			
			#ifdef HW_IOT_MODE
			/* TO-DO */
			#else
			if(1 == ucReadDone){
				ucReadDone = 0;
			}else if(0 == ucReadDone){
				ucReadTry++;
			}
			if(1 == ucReadTry){
				stMsg.usRevLen = 128;
				nbiot_data_recv(stMsg.iFd, (int *)&stMsg.usRevLen, stMsg.aucMsgData, iSz, 10);
				ucReadTry = 0;
				HAL_Delay(1000);
			}
			#endif
		}

		if(0 < stMsg.usRevLen){
				//0038020D424332384A412D30322D53544403165353422C563135305231303043313042323030535031040F383637373236303331363030303032
			  //    040F383637373236303331363737343839
			  //    040F383637373236303331363737343937
			  //    040F383637373236303331363737333331
				//001A040F383637373236303331363737333331CA0101A10101A20101
				//0022040F383637373236303331363737343839CA0101A10102A30A4C434420546573742031
			  //001A040F383637373236303331363737343937CA0101A10103A20101
				//001A040F383637373236303331363737343937CA0101A10104A20101
				//001A040F383637373236303331363737343937CA0101A10105A20101
			  
				// COAP
			  //AAAA0000
			#ifdef HW_IOT_MODE
			parse_coap_msg(&stMsg);
			if(0 != stMsg.ucCmd && MSG_ACK != stMsg.ucCmd){
				ucStep = M_CTL_ACK;//M_MCU_STOP;
			}
			#else
			parse_msg(&stMsg);
			if(0 != stMsg.ucCmd){
				ucStep = M_UP_SENSER;
			}
			#endif
			stMsg.usRevLen = 0;
			
			switch(stMsg.ucCmd){
				case CTL_LED: // LED
					if(1 == stMsg.ucCmdVal){
						HAL_GPIO_WritePin(RGB_R_GPIO_Port, RGB_R_Pin|RGB_G_Pin|RGB_B_Pin, GPIO_PIN_RESET);
					}else{
						HAL_GPIO_WritePin(RGB_R_GPIO_Port, RGB_R_Pin|RGB_G_Pin|RGB_B_Pin, GPIO_PIN_SET); stMsg.ucCmdVal = 0;
					}
					break;
				case CTL_LCD: // LCD
					OLED_Clear();
					OLED_ShowString(0, 0, (uint8_t *)stMsg.aucCmdMsg, 8);
					s_UserShow = 1;
					break;
				case CTL_SWITCH_1: // SW1
					
					HAL_GPIO_WritePin(JDQ1_GPIO_Port, JDQ1_Pin, GPIO_PIN_SET);
					HAL_Delay(200);
					HAL_GPIO_WritePin(JDQ1_GPIO_Port, JDQ1_Pin, GPIO_PIN_RESET); stMsg.ucCmdVal = 0;
					/*if(1 == stMsg.ucCmdVal){
						HAL_GPIO_WritePin(JDQ1_GPIO_Port, JDQ1_Pin, GPIO_PIN_SET);
					}else{
						HAL_GPIO_WritePin(JDQ1_GPIO_Port, JDQ1_Pin, GPIO_PIN_RESET); stMsg.ucCmdVal = 0;
					}*/
					break;
				case CTL_SWITCH_2: // SW2
					if(1 == stMsg.ucCmdVal){
						HAL_GPIO_WritePin(JDQ2_GPIO_Port, JDQ2_Pin, GPIO_PIN_SET);
					}else{
						HAL_GPIO_WritePin(JDQ2_GPIO_Port, JDQ2_Pin, GPIO_PIN_RESET); stMsg.ucCmdVal = 0;
					}
					break;
				case CTL_SWITCH_12: // SW1&2
					if(1 == stMsg.ucCmdVal){
						HAL_GPIO_WritePin(JDQ2_GPIO_Port, JDQ1_Pin|JDQ2_Pin, GPIO_PIN_SET);
					}else{
						HAL_GPIO_WritePin(JDQ2_GPIO_Port, JDQ1_Pin|JDQ2_Pin, GPIO_PIN_RESET); stMsg.ucCmdVal = 0;
					}
					/****************** coap ********************/
				case MSG_ACK:
					printf("msg up ok\r\n");
					break;
			}
		}
		do{
			UART_Forward();
		}while(0 == uart1_is_empty());
		#else
		UART_Forward();
		#endif
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  /** Configure LSE Drive Capability 
  */
  HAL_PWR_EnableBkUpAccess();
  __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_LSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 1;
  RCC_OscInitStruct.PLL.PLLN = 8;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_USART1
                              |RCC_PERIPHCLK_USART2|RCC_PERIPHCLK_USART3
                              |RCC_PERIPHCLK_ADC;
  PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
  PeriphClkInit.Usart3ClockSelection = RCC_USART3CLKSOURCE_PCLK1;
  PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_PLLSAI1;
  PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
  PeriphClkInit.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_HSE;
  PeriphClkInit.PLLSAI1.PLLSAI1M = 1;
  PeriphClkInit.PLLSAI1.PLLSAI1N = 8;
  PeriphClkInit.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV7;
  PeriphClkInit.PLLSAI1.PLLSAI1Q = RCC_PLLQ_DIV2;
  PeriphClkInit.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2;
  PeriphClkInit.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_ADC1CLK;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure the main internal regulator output voltage 
  */
  if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */
void STOP_MCU(void)
{
	/*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, JDQ1_Pin|GPIO_PIN_13|GPIO_PIN_14|JDQ2_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, STATE_Pin|RGB_G_Pin|RGB_R_Pin|RGB_B_Pin, GPIO_PIN_SET);
	#if 0
	GPIO_InitTypeDef GPIO_InitStructure;
	
	//GPIO_InitStructure.Pin = GPIO_PIN_All;
  GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStructure.Pull = GPIO_NOPULL;
	
	GPIO_InitStructure.Pin = GPIO_PIN_0|KEY2_Pin|GPIO_PIN_1|GPIO_PIN_6|GPIO_PIN_4;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_InitStructure.Pin = GPIO_PIN_13|GPIO_PIN_14|STATE_Pin|GPIO_PIN_8|GPIO_PIN_9;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_InitStructure.Pin = KEY1_Pin;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
	#endif
	/* Disable GPIOs clock */
  __HAL_RCC_GPIOA_CLK_DISABLE();
  __HAL_RCC_GPIOB_CLK_DISABLE();
  __HAL_RCC_GPIOC_CLK_DISABLE();
	__HAL_RCC_GPIOH_CLK_DISABLE();
	
	MX_RTC_Init();
	
	
	
	
	//SLEEP MODE
	//printf("sleep mode\n");
	//HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFE);
	
	//LOWER SLEEP MODE
	//printf("low-power sleep mode\n");
	//HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFE);
	
	//STOP MODE
	printf("stop mode\n");
	HAL_PWREx_EnterSTOP1Mode(PWR_STOPENTRY_WFE);
	
	//STANDBY MODE
	//printf("Standby mode\n");
	//HAL_PWR_EnterSTANDBYMode();
	
	//SHUTDOWN MODE
	//printf("Shutdown mode\n");
	//HAL_PWREx_EnterSHUTDOWNMode();
}

void SYSCLKConfig_RESET(void)
{
	
	SystemClock_Config();

	/* Disable all used wakeup source */
	HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);

	/*重新初始化所有外设配*/
	MX_GPIO_Init();
  MX_DMA_Init();
  
  TIM_ReInit();
	
	ADC_ReInit();
	UART_ReInit();
	printf("restart MCU\n");
}

void SYSCLKConfig_RESET_UART(void)
{
	
	SystemClock_Config();

	UART_ReInit();
	printf("RESET_UART\n");
}

void KE1_Test_Itself(void)
{
	int iDelay = 500;
	char acBuf[16] = {0};
	int iSz = sizeof(acBuf), iRet = 0;
	float	temperature = 0.0; // temperature
	float	humidity = 0.0; // relative humidity [%RH]
	
	TIM_PWM_Start();HAL_Delay(300);TIM_PWM_Stop();
	
	HAL_Delay(iDelay);
	OLED_Clear();
	
	OLED_ShowString(0, 0, (uint8_t *)"Check Module .", 8);
	nbiot_send_at_cmd(AT, 300);
	iRet = nbiot_recv_at_resp(10, acBuf, &iSz);
	if(2 == iRet){
	OLED_ShowString(0, 0, (uint8_t *)"Module Failed.", 8);
	}else{
	OLED_ShowString(0, 0, (uint8_t *)"Module Ok     ", 8);
	}
	
	OLED_ShowString(0, 0, (uint8_t *)"J1 On ...     ", 8);
	HAL_GPIO_WritePin(JDQ1_GPIO_Port, JDQ1_Pin, GPIO_PIN_SET);// on
	HAL_Delay(iDelay);
	
	OLED_ShowString(0, 0, (uint8_t *)"J1 Off ...    ", 8);
	HAL_GPIO_WritePin(JDQ1_GPIO_Port, JDQ1_Pin, GPIO_PIN_RESET);//off
	HAL_Delay(iDelay);
	
	OLED_ShowString(0, 0, (uint8_t *)"J2 On ...     ", 8);
	HAL_GPIO_WritePin(JDQ2_GPIO_Port, JDQ2_Pin, GPIO_PIN_SET);
	HAL_Delay(iDelay);
	
	OLED_ShowString(0, 0, (uint8_t *)"J2 Off ...    ", 8);
	HAL_GPIO_WritePin(JDQ2_GPIO_Port, JDQ2_Pin, GPIO_PIN_RESET);
	HAL_Delay(iDelay);
	
	OLED_ShowString(0, 0, (uint8_t *)"LED On ...    ", 8);
	HAL_GPIO_WritePin(RGB_R_GPIO_Port, RGB_R_Pin|RGB_G_Pin|RGB_B_Pin, GPIO_PIN_RESET);
	HAL_Delay(iDelay);
	OLED_ShowString(0, 0, (uint8_t *)"LED Off ...   ", 8);
	HAL_GPIO_WritePin(RGB_R_GPIO_Port, RGB_R_Pin|RGB_G_Pin|RGB_B_Pin, GPIO_PIN_SET);
	
	OLED_ShowString(0, 0, (uint8_t *)"BEEP ...      ", 8);
	TIM_PWM_Start();
	
	OLED_ShowString(0, 0, (uint8_t *)"Press K1 ...  ", 8);
	do{
		HAL_Delay(100);
	}while(0 == s_QCk1flag);
	
	OLED_ShowString(0, 0, (uint8_t *)"Press K2 ..", 8);
	do{
		HAL_Delay(100);
	}while(0 == s_QCk2flag);
	
	TIM_PWM_Stop();
	
	ADC_Start();
	HAL_Delay(500);
	stMsg.usVoltage = ADC_Battery_Voltage();
	stMsg.usLight = ADC_Light_Val();
	stMsg.usSound = ADC_Sound_Val();
	ADC_Stop();
	
	SHT3X_GetTempAndHumi(&temperature, &humidity, REPEATAB_HIGH, MODE_CLKSTRETCH, 2);
	
	snprintf(acBuf, sizeof(acBuf), "%.2f'C/%.2f%%", temperature, humidity);
	OLED_ShowString(0, 0, (uint8_t *)acBuf, 8);
	
	snprintf(acBuf, sizeof(acBuf), "%d/%d/%d", stMsg.usVoltage, stMsg.usLight, stMsg.usSound);
	OLED_ShowString(0, 2, (uint8_t *)acBuf, 8);
	
	s_SwitchOLED = 0; s_ClearOLED = 1; s_UserShow = 1;
	Flash_Write_Flag(FLASH_QC_FLAG_VAL);
	
	HAL_GPIO_WritePin(RGB_R_GPIO_Port, RGB_R_Pin|RGB_G_Pin|RGB_B_Pin, GPIO_PIN_SET);
	HAL_GPIO_WritePin(JDQ2_GPIO_Port, JDQ1_Pin|JDQ2_Pin, GPIO_PIN_RESET);
	HAL_Delay(2500);
	OLED_Clear();
}
/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */

  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(char *file, uint32_t line)
{ 
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
